<template>
	<div class="custom-uploader">
		<!-- 上传控件 -->
		<van-uploader v-model="fileList" :after-read="afterRead" :before-read="beforeRead" :max-count="maxCount"
			:max-size="maxSize" :multiple="multiple" :accept="accept" result-type="file"
			:preview-full-image="previewFullImage" :before-delete="handleBeforeDelete" :preview-image="previewImage">
		</van-uploader>
		<!--      <template #default>-->
		<!--        <div class="upload-area">-->
		<!--          <van-icon name="plus" size="24" />-->
		<!--          <span v-if="uploadText">{{ uploadText }}</span>-->
		<!--        </div>-->
		<!--      </template>-->

		<!--      <template #file="file">-->
		<!--        <div class="file-item">-->
		<!--          <img :src="file.content" class="preview-img" v-if="isImage(file)">-->
		<!--          <div class="file-info" v-else>-->
		<!--            <van-icon name="description" size="24" />-->
		<!--            <div class="file-name">{{ file.file.name }}</div>-->
		<!--          </div>-->
		<!--          <div class="file-status">-->
		<!--            <van-loading v-if="file.status === 'uploading'" size="20" />-->
		<!--            <van-icon-->
		<!--                v-else-if="file.status === 'failed'"-->
		<!--                name="close"-->
		<!--                color="#ee0a24"-->
		<!--                size="20"-->
		<!--            />-->
		<!--          </div>-->
		<!--        </div>-->
		<!--      </template>-->
		<!--    </van-uploader>-->
	</div>
</template>

<script setup>
	import {
		ref
	} from 'vue';
	import {
		Dialog,
		showDialog,
		ImagePreview,
		showToast
	} from 'vant';
	import {
		getToken
	} from '@/utils/auth';
	import axios from "axios";


	const props = defineProps({
		// 上传接口地址
		action: {
			type: String,
			required: true
		},
		name: {
			type: String,
			// required: true
		},
		// 允许的文件类型
		accept: {
			type: String,
			default: 'image/*'
		},
		// 最大文件大小
		maxSize: {
			type: Number,
			default: 500 * 1024
		},
		// 最大上传数量
		maxCount: {
			type: Number,
			default: 1
		},
		// 是否多选
		multiple: {
			type: Boolean,
			default: false
		},
		// 上传区域文字提示
		uploadText: String,
		// 是否开启图片预览
		previewImage: {
			type: Boolean,
			default: true
		},
		//是否在点击预览图后展示全屏图片预览
		previewFullImage: {
			type: Boolean,
			default: false
		}
	})

	const emit = defineEmits(['upload-success', 'delete', "update:modelValue", "on-delete"])

	const fileList = ref([])

	// 文件校验逻辑
	const beforeRead = (file) => {

		return new Promise((resolve, reject) => {
			const files = Array.isArray(file) ? file : [file];

			// 检查文件数量
			if (files.length + fileList.value.length > props.maxCount) {
				showToast({
					type: 'fail',
					message: `最多上传${props.maxCount}个文件`
				});
				return reject();
			}

			// 检查文件类型
			const acceptTypes = props.accept.split(',').map(t => t.trim());
			const isValidType = files.every(item => {
				return acceptTypes.some(type => {
					if (type === '*') return true;
					if (type.endsWith('/*')) return item.type.startsWith(type.split('/')[0]);
					return item.type === type;
				});
			});

			if (!isValidType) {
				showToast({
					type: 'fail',
					message: `只支持${props.accept}格式文件`
				});
				return reject();
			}

			// 检查文件大小
			const maxSizeBytes = props.maxSize * 1024 * 1024;
			const isValidSize = files.every(item => item.size <= maxSizeBytes);

			if (!isValidSize) {
				showToast({
					type: 'fail',
					message: `文件大小不能超过${props.maxSize}MB`
				});
				return reject();
			}

			resolve(file); // 校验通过
		});
	};

	// 处理上传
	const afterRead = async (file) => {
		const files = Array.isArray(file) ? file : [file];
		for (const item of files) {
			try {
				// 找到当前文件在 fileList 中的索引
				const index = fileList.value.findIndex(f => f === item);
				if (index === -1) continue;

				// 更新状态为上传中
				fileList.value[index].status = 'uploading';

				// 这里替换为实际的上传逻辑
				const formData = new FormData()

				formData.append('file', item.file)

				// 使用 axios 上传
				const response = await axios.post(props.action, formData, {
					headers: {
						'Content-Type': 'multipart/form-data',
						'token': '' + getToken(),
					}
				});
				if (response.status === 200) {
					fileList.value[index].status = 'done';
					fileList.value[index].url = response.data.data.url;
					emit('upload-success', {
						name: props.name, // 携带标识符
						fileData: response.data,
						list: fileList.value
					})
				} else {
					fileList.value[index].status = 'failed';
					showToast({
						type: 'fail',
						message: '上传失败'
					});
				}
				/*
				if (response.ok) {
					item.status = 'done'
					// 这里根据实际接口返回结构调整
					item.url = result.url
					// emit('upload-success', result)
				} else {
					item.status = 'failed'
				}*/
			} catch (error) {
				//console.error('上传错误:', error);
				fileList.value[index].status = 'failed';
				showToast({
					type: 'fail',
					message: '上传失败'
				});
			}
		}
	}
	// 自定义删除事件
	const handleBeforeDelete = (file) => {
		return new Promise((resolve, reject) => {
			showDialog({
				title: "确认删除",
				message: "确定要删除该文件吗？",
				showCancelButton: true
			}).then(() => {
				// 过滤掉删除的文件并更新 modelValue
				fileList.value = fileList.value.filter(item => item !== file);
				// 触发 on-delete 事件，通知父组件
				emit('on-delete', {
					name: props.name, // 携带标识符
					file: file,
				})
				// emit("update:modelValue", fileList.value);

				resolve(true); // 确认删除
			}).catch(() => {
				reject(false); // 取消删除
			});
		});
	};

	// 处理删除
	const handleDelete = (file) => {
		showDialog({
			message: '确定删除该文件吗？',
		}).then(() => {
			const index = fileList.value.findIndex(f => f === file)
			if (index > -1) {
				fileList.value.splice(index, 1)
				emit('delete', file)
			}
		}).catch(() => {
			// on cancel
		});
	}

	// 判断是否为图片
	const isImage = (file) => {
		return file.file.type.startsWith('image/')
	}

	// 图片预览
	const showPreview = (file) => {
		if (isImage(file)) {
			ImagePreview([file.url || file.content])
		}
	}
</script>

<style lang="scss" scoped>
	.custom-uploader {
		--upload-area-size: 100px;
	}

	.upload-area {
		width: var(--upload-area-size);
		height: var(--upload-area-size);
		background: #f7f8fa;
		border-radius: 8px;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		color: #969799;
	}

	.file-item {
		position: relative;
		width: var(--upload-area-size);
		height: var(--upload-area-size);
		border-radius: 8px;
		overflow: hidden;

		.preview-img {
			width: 100%;
			height: 100%;
			object-fit: cover;
		}

		.file-info {
			padding: 8px;
			text-align: center;

			.file-name {
				font-size: 12px;
				word-break: break-all;
				display: -webkit-box;
				-webkit-line-clamp: 2;
				-webkit-box-orient: vertical;
				overflow: hidden;
			}
		}

		.file-status {
			position: absolute;
			top: 4px;
			right: 4px;
			background: rgba(0, 0, 0, 0.5);
			border-radius: 50%;
			padding: 2px;
		}
	}
</style>
